package gw.com.android.ui.bulletin;

import android.text.TextUtils;
import android.util.Log;

import com.gwtsz.gts2.hx.BuildConfig;
import com.gwtsz.gts2.hx.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;

import gw.com.android.app.AppMain;
import gw.com.android.app.GTConfig;
import gw.com.android.greendao.NotifyDataHelper;
import gw.com.android.presenter.http.HttpCallback;
import gw.com.android.presenter.http.Https;
import gw.com.android.utils.CacheUtils;
import gw.com.android.utils.ENV;
import okhttp3.Request;
import okhttp3.Response;
import www.com.library.app.Logger;
import www.com.library.util.AESCrypto3;
import www.com.library.util.DeviceUtil;
import www.com.library.util.Md5;
import www.com.library.util.StringUtils;

/**
 * @author jett
 * @since 2018-07-27.
 */
public class NotifyRequest {

    private static List<Long> readedIds;
    private volatile static boolean isRunning = false;

    public HashMap<Integer, String> fetchCategory() {
        String str = CacheUtils.readFile("notify_category.data");
        if (!TextUtils.isEmpty(str)) {
            return parseCategory(str, true, false);
        }
        return null;
    }

    public HashMap<Integer, String> fetchAllCategory() {
        String str = CacheUtils.readFile("notify_category.data");
        if (!TextUtils.isEmpty(str)) {
            return parseCategory(str, false, false);
        }
        return null;
    }

    public void getCategory(final HttpCallback<HashMap<Integer, String>> callback) {
        String url = "https://openapi.hx9999.com/tools/";
        Https https = new Https(url);
        https.addParam("service", "Pushsystem.getTypeList");
        https.addParam("terminal", "android");
        https.addParam("company_id", "18");
        StringBuilder sign = new StringBuilder();
        Collection<String> signs = new TreeMap<>(https.getParam()).values();
        for (String str : signs) {
            sign.append(str);
        }
        https.addParam("sign", Md5.md5((sign + BuildConfig.openApiSignKey).getBytes()));
        https.get(new Https.ResponseCallback<String>() {
            @Override
            public void onSuccess(Request request, Response response, String result, int code) {
                HashMap<Integer, String> map = parseCategory(result, true, true);
                if (callback != null) {
                    callback.onSuccess(map);
                }
            }

            @Override
            public void onFailure(Request request, IOException e) {
                Logger.e("_notify", e);
                if (callback != null) {
                    callback.onFailure(e);
                }
            }
        });
    }

    /**
     * @param filterParent 只取父类
     * @param cache        缓存到本地
     */
    private HashMap<Integer, String> parseCategory(String result, boolean filterParent, boolean cache) {
        if (TextUtils.isEmpty(result)) {
            return null;
        }
        try {
            JSONObject jsonObject = new JSONObject(result);
            JSONArray dataArr = jsonObject.optJSONArray("data");
            if (dataArr != null && dataArr.length() > 0) {
                HashMap<Integer, String> map = new LinkedHashMap<>();
                for (int i = 0; i < dataArr.length(); i++) {
                    JSONObject json = dataArr.optJSONObject(i);
                    if (json != null) {
                        int pid = json.optInt("pid", -1);
                        if (filterParent && pid != 0) {
                            continue;
                        }
                        int typeId = json.optInt("id");
                        String typeName = json.optString("message_type");
                        if (GTConfig.instance().getAccountType() != GTConfig.ACC_TYPE_REAL) {
                            if ("分析师订阅".equals(typeName) || "互动提醒".equals(typeName)) {
                                continue;
                            }
                        }
                        map.put(typeId, typeName);
                    }
                }
                if (cache) {
                    CacheUtils.writeFile("notify_category.data", result);
                }
                return map;
            }
        } catch (JSONException e) {
            Logger.e("_notify", e);
        }
        return null;
    }

    public void getNoticeList(String userId, final HttpCallback<List<NotifyData>> callback) {
        Logger.i("_notify", "getNoticeList : isRunning = " + isRunning);
        if (isRunning) {
            if (callback != null) {
                callback.onFailure(null);
            }
            return;
        }
        isRunning = true;
        Https https = new Https("https://openapi.hx9999.com/tools/");
        String service = "Pushsystem.getPushInfoListV2";
        https.addParam("service", service);
        https.addParam("sendChannel", "App");
        https.addParam("terminal", "android");
        https.addParam("company_id", "18");
        https.addParam("appkeys", getJpushKey());
        String deviceId = DeviceUtil.instance().getMacAddr(AppMain.getApp());
        try {
            https.addParam("deviceId", AESCrypto3.Encrypt(Md5.md5(deviceId.getBytes())));
            if (!StringUtils.isEmpty(userId)) {
                https.addParam("loginAccount", AESCrypto3.Encrypt(userId));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long timeStamp = getTimeStamp();
        if (timeStamp > 0) {
            https.addParam("dataTime", String.valueOf(timeStamp));
        }

        StringBuilder sign = new StringBuilder();
        Collection<String> signs = new TreeMap<>(https.getParam()).values();
        for (String str : signs) {
            sign.append(str);
        }
        https.addParam("sign", Md5.md5((sign + BuildConfig.openApiSignKey).getBytes()));
        https.responseOnUiThread(false);
        Logger.i("_notify", "getNoticeList start timestamp = " + timeStamp);
        https.get(new Https.ResponseCallback<String>() {
            @Override
            public void onSuccess(Request request, Response response, String result, int code) {
                Logger.e("_notify", "getNoticeList onSuccess");
                sendResult(parse(result), callback);
                isRunning = false;
            }

            @Override
            public void onFailure(Request request, IOException e) {
                Logger.e("_notify", e);
                sendException(e, callback);
                isRunning = false;
            }
        });
    }

    private List<NotifyData> parse(String result) {
        if (TextUtils.isEmpty(result)) {
            return null;
        }
        try {
            JSONObject jsonObject = new JSONObject(result);
            JSONObject dataJson = jsonObject.optJSONObject("data");
            Logger.e("_notify", "parse json");
            if (dataJson != null) {
                JSONArray jsonArray = dataJson.optJSONArray("list");
                Logger.e("_notify", "parse jsonArray is null ? " + (jsonArray == null));
                if (jsonArray != null && jsonArray.length() > 0) {
                    List<NotifyData> entities = new ArrayList<>();
                    List<Long> ids = new ArrayList<>();
                    long timeStamp = getTimeStamp();
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject json = jsonArray.optJSONObject(i);
                        if (json != null) {
                            NotifyData notice = new NotifyData();
                            notice._id = json.optLong("id");

                            notice.title = json.optString("title");
                            notice.description = json.optString("description");
                            notice.ctime = json.optLong("ctime");
                            notice.typeId = json.optInt("typeId");
                            notice.dataId = json.optString("dataId");
                            notice.typeParentId = json.optInt("typepId");
                            if (notice.typeParentId != NotifyCategoryActivity.TYPE_ID) {
                                continue;
                            }
                            notice.isBurn = "Y".equals(json.optString("is_burn"));
                            notice.isReaded = false;
                            if (readedIds != null && readedIds.remove(notice._id)) {
                                if (notice.isBurn) {
                                    continue;
                                }
                                notice.isReaded = true;
                            }
                            notice.displaySecond = json.optLong("app_display_second", -1);
                            if (notice.displaySecond <= 0) {
                                continue;
                            }
                            notice.createTime = System.currentTimeMillis() / 1000;
                            if (notice.ctime > timeStamp) {
                                timeStamp = notice.ctime;
                            }
                            if (!NotifyDataHelper.exsit(notice._id)) {
                                entities.add(notice);
                                ids.add(notice._id);
                            }
                        }
                    }
                    if (timeStamp > 0) {
                        setTimeStamp(timeStamp);
                    }
                    Logger.e("_notify", "parse entities : " + entities.size());
                    addNewNotifyId(ids);
                    NotifyDataHelper.insertOrReplace(entities);
                    NotifyDataHelper.notifyChange();
                    return entities;
                }
            }
        } catch (JSONException e) {
            Logger.e(e);
        }
        return null;
    }

    private void sendResult(final List<NotifyData> result, final HttpCallback<List<NotifyData>> callback) {
        if (callback != null) {
            AppMain.getApp().getHandler().post(new Runnable() {
                @Override
                public void run() {
                    callback.onSuccess(result);
                }
            });
        }
    }

    private void sendException(final Exception e, final HttpCallback<List<NotifyData>> callback) {
        if (callback != null) {
            AppMain.getApp().getHandler().post(new Runnable() {
                @Override
                public void run() {
                    callback.onFailure(e);
                }
            });
        }
    }

    /**
     * 新消息的id ，用于
     *
     * @see NotifyCategoryActivity 中的new标签
     */
    public List<Long> getNewNotifyId() {
        String str = CacheUtils.readFile(getNewNotifyCacheFileName());
        if (!TextUtils.isEmpty(str)) {
            str = str.replaceAll("\n", "");
            String[] split = str.split(",");
            List<Long> list = new ArrayList<>();
            for (String id : split) {
                if (!TextUtils.isEmpty(id)) {
                    list.add(Long.parseLong(id));
                }
            }
            return list;
        }
        return null;
    }

    /**
     * 新消息的id ，用于
     *
     * @see NotifyCategoryActivity 中的new标签
     */
    private void addNewNotifyId(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        synchronized (NotifyRequest.class) {
            List<Long> newNotifyId = getNewNotifyId();
            if (newNotifyId == null) {
                storeNewNotifyId(ids);
                return;
            }
            newNotifyId.addAll(ids);
            storeNewNotifyId(newNotifyId);
        }
    }

    /**
     * 新消息的id ，用于
     *
     * @see NotifyCategoryActivity 中的new标签
     */
    public void deleteNewNotifyId(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        synchronized (NotifyRequest.class) {
            List<Long> newNotifyId = getNewNotifyId();
            if (newNotifyId == null) {
                return;
            }
            newNotifyId.removeAll(ids);
            storeNewNotifyId(newNotifyId);
        }
    }

    /**
     * 新消息的id ，用于
     *
     * @see NotifyCategoryActivity 中的new标签
     */
    private void storeNewNotifyId(List<Long> ids) {
        StringBuilder sb = new StringBuilder("");
        if (ids != null) {
            int size = ids.size();
            if (size > 200) {
                ids = ids.subList(size - 180, size);
            }
            for (Long id : ids) {
                sb.append(id).append(",");
            }
        }
        CacheUtils.writeFile(getNewNotifyCacheFileName(), sb.toString());
    }

    private String getNewNotifyCacheFileName() {
        return GTConfig.instance().mCurName + "_new_notify_id.data";
    }

    private long getTimeStamp() {
        return GTConfig.instance().getLongValue("push_time_stamp_" + GTConfig.instance().mCurName, -1);
    }

    private void setTimeStamp(long value) {
        GTConfig.instance().setLongValue("push_time_stamp_" + GTConfig.instance().mCurName, value);
    }

    private String getJpushKey() {
        return AppMain.getApp().getResources().getString(ENV.isUat() ? R.string.jpush_key_uat : R.string.jpush_key_prd);
    }

    /**
     * 从推送进入到消息详情，如果该消息还未被拉取到本地，但状态却被标记为已读
     * 所以，记录该ID，并且重新拉取消息中心的消息。
     */
    public static void handlerReadedId(long id) {
        if (readedIds == null) {
            readedIds = Collections.synchronizedList(new ArrayList<Long>());
        }
        readedIds.add(id);
        AppMain.getApp().getHandler().postDelayed(new Runnable() {
            @Override
            public void run() {
                new NotifyRequest().getNoticeList(GTConfig.instance().mCurName, null);
            }
        }, 3000);
    }

}
